package com.oot2d.states;

import com.oot2d.entity.Player;
import com.oot2d.event.Action;
import com.oot2d.event.EventManager;
import com.oot2d.util.API;
import com.oot2d.util.Console;
import org.newdawn.slick.*;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import com.oot2d.ui.HUD;
import com.oot2d.ui.Items;
import com.oot2d.ui.Menu;
import com.oot2d.ui.Target;
import com.oot2d.util.InputManager;
import com.oot2d.util.WorldManager;
import com.oot2d.world.Camera;

import java.util.LinkedList;

public class Game extends BasicGameState {
    private int stateID;
    private Camera cam;
    private Player link;
    private Target target;
    private HUD hud;
    private Menu menu;
    private API api;
    private Console console;

    private static EventManager events;

    private boolean paused = false;

    public Game(int id)
    {
        stateID = id;
    }

    public void init(GameContainer gc, StateBasedGame sbg) throws SlickException
    {
        EventManager.init();
        InputManager.init();
        WorldManager.init();
        WorldManager.loadWorld(1);
        link = new Player();
        link.spawn();
        hud = new HUD(link);
        menu = new Menu();
        cam = new Camera();
        api = new API();

        events = new EventManager();

        //Set up scripting console
        UnicodeFont f = new UnicodeFont(new java.awt.Font("Consolas", java.awt.Font.PLAIN, 14));
        f.getEffects().add(new ColorEffect(java.awt.Color.white));
        f.addNeheGlyphs();
        f.loadGlyphs();
        console = new Console(gc, f);

        //Test
        Items.test();
    }

    public void update(GameContainer gc, StateBasedGame sbg, int d) throws SlickException
    {
        EventManager.updateTimers(d);
        InputManager.setKeys(gc);

        //Debug
        if (gc.getInput().isKeyPressed(Input.KEY_GRAVE))
            console.toggle();

        if (console.hasFocus())
            InputManager.clearKeys();

        if (InputManager.esc()) {
            if (!paused)
                menu.openMenu();
            else
                menu.playClose();

            paused = !paused;
        }

        hud.update(d);

        if (paused) {
            menu.update(gc, d);
            return;
        }

        WorldManager.currentWorld.update(d);

        link.update(d);
        cam.lookAt(link);

        if (link.getTarget() != null && target == null)
            target = new Target(link.getTarget());
        else if (link.getTarget() == null)
            target = null;

        if (target != null)
            target.update(d);
    }

    public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException
    {
        //Render world
        cam.adjust(g);
        WorldManager.currentWorld.render(g, 0, cam.getX(), cam.getY());
        cam.reset(g);

        //Render link if he is on the ground level
        g.translate((cam.leftEdge() || cam.rightEdge()) ? -(240.0f - (link.getX() - cam.getX())) : 0,
                (cam.topEdge() || cam.bottomEdge()) ? -(160.0f - (link.getY() - cam.getY())) : 0);
        if (link.getZ() == 0)
            link.draw();
        g.translate((cam.leftEdge() || cam.rightEdge()) ? (240.0f - (link.getX() - cam.getX())) : 0,
                (cam.topEdge() || cam.bottomEdge()) ? (160.0f - (link.getY() - cam.getY())) : 0);

        //Render tiles above link
        cam.adjust(g);
        WorldManager.currentWorld.renderOverlay(0, cam.getX(), cam.getY());
        cam.reset(g);

        //Render second level if it exists
        if (WorldManager.currentWorld.hasTop()) {
            cam.adjust(g);
            WorldManager.currentWorld.render(g, 1, cam.getX(), cam.getY());
            cam.reset(g);
        }

        //Render link if he is on the second level
        g.translate((cam.leftEdge() || cam.rightEdge()) ? -(240.0f - (link.getX() - cam.getX())) : 0,
                (cam.topEdge() || cam.bottomEdge()) ? -(160.0f - (link.getY() - cam.getY())) : 0);
        if (link.getZ() == 1)
            link.draw();
        g.translate((cam.leftEdge() || cam.rightEdge()) ? (240.0f - (link.getX() - cam.getX())) : 0,
                (cam.topEdge() || cam.bottomEdge()) ? (160.0f - (link.getY() - cam.getY())) : 0);

        //Render second level's overlay tiles
        if (WorldManager.currentWorld.hasTop()) {
            cam.adjust(g);
            WorldManager.currentWorld.renderOverlay(1, cam.getX(), cam.getY());
            cam.reset(g);
        }

        //Render z-target crosshair
        if (target != null) {
            cam.adjust(g);
            target.render(g);
            cam.reset(g);
        }



        //Rutger is silly
        if (paused) {
            menu.render(gc, g);
            WorldManager.currentWorld.getMusic().setVolume(0.05f);
        } else if (WorldManager.currentWorld.getMusic().getVolume() < 0.3f) {
            WorldManager.currentWorld.getMusic().setVolume(0.3f);
        }

        hud.render(g);

        //Debug
        console.render(gc, g);
    }

    public int getID()
    {
        return stateID;
    }

    public static EventManager getEvents()
    {
        return events;
    }
}
